package org.speed.data;

import java.util.Date;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**
 * Hello world!
 *
 */
public class App 
{
    public static void main( String[] args ) throws InterruptedException
    {
    	
        
        //qos1();
    	
    	
    }
    
    
    public static void qos1() {
    	
    	Qos qos = new Qos();
    	qos.setLimit(20);
    	qos.setPeriod(1000L);
    	
    	ExecutorService exec = Executors.newFixedThreadPool(20);
    	while(true) {
    		
    		exec.execute(new Runnable() {
				
				@Override
				public void run() {
					
					boolean limit = qos.isLimit();
					if(limit) {
						//System.out.println("#" + Thread.currentThread().getName() + ",run....");
						try {
							Thread.sleep(20);
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
					}
					
				}
			});
    	}
    	
    	
    	
    }
    
    
    static class Qos {
    	
    	private Long period;
    	
    	private Integer limit;
    	
    	private Integer count = 0;
    	
    	private Long lastReqTime;
    	
    	private Long limitQpsTime;
     	
    	public Qos(){
    		
    	}
    	
    	public synchronized boolean isLimit() {
    		long now = System.currentTimeMillis();
    		if(lastReqTime == null) {
    			lastReqTime = System.currentTimeMillis();
    		}

    		if(now - lastReqTime < period && count >= limit ) {
    			
    			if(limitQpsTime == null) {
    				System.out.println("限流了:" + new Date().toLocaleString());
    				
    				count = 0;
        			lastReqTime = System.currentTimeMillis();
        			limitQpsTime = lastReqTime / 1000 * 1000 ; 
        			return false;
    			}
    			
    			
    			if(limitQpsTime == now / 1000 * 1000  ) {
    				//System.out.println("限流了:" + new Date().toLocaleString());
    				return false;
    			}
    			
    		}
    		
    		lastReqTime = System.currentTimeMillis();
    		count++;
    		return true;
    	}
    	
    	

		public Long getPeriod() {
			return period;
		}

		public void setPeriod(Long period) {
			this.period = period;
		}

		public Integer getLimit() {
			return limit;
		}

		public void setLimit(Integer limit) {
			this.limit = limit;
		}

		public Integer getCount() {
			return count;
		}

		public void setCount(Integer count) {
			this.count = count;
		}
    	
    }
}
